#include "main.h"
#include "flash.h"
#include "lib.h"
#include "app_input.h"
#include "rd_data_ctrl.h"
#include "app_can.h"
#include "hek1008.h"
#include "app_output.h"
#include "enet_eval.h"
#include "drv_dac.h"
#include "i2c1.h"
#include "drv_spi.h"
#include "modbus_timer.h"
#include "user_app.h"
#include "drv_wdt.h"
#include "drv_pi.h"
#include "task_modbus.h"
#include "mb_master_app.h"
#include "netconf.h"
#include "FreeRTOS.h"
#include "task.h"
#include "task_cycle.h"
#include "hek1016.h"
#include "para.h"
#include "app_output.h"
#include "parameter_config.h"
#include "pt100.h"

extern uint32_t g_out_timeout_cntr;

uint8_t code_dateStr[] = __DATE__;
uint8_t code_timeStr[] = __TIME__;
uint32_t g_year   = YEAR;
uint32_t g_month   = MONTH+1;
uint32_t g_day    = DAY;
uint32_t g_hour   = HOUR;
uint32_t g_minute = MINUTE;
uint32_t g_second    = SECOND;
uint32_t g_inited = 0;



/*
状态指示灯：在boot程序中运行，状态指示灯每100ms闪烁一次，快闪；
	         在APP程序中运行，状态指示灯用于以太网连接状态检测，常亮：以太网连接成功；常灭：以太网连接失败；
		       在APP程序运行初始30S，快闪，然后每500ms闪烁一次，主要用于测试
*/
uint8_t uc_enet_status_flag = 0;//常亮：以太网连接成功；常灭：以太网连接失败；
uint8_t uc_enet_is_valid    = 0;//0:以太网无效，1：以太网有效
/*
错误指示灯：CAN接收通信错误，长亮，同时CAN通信指示灯快速闪烁；
           CAN发送通信错误，不亮，同时CAN通信指示灯快速闪烁;
           如果接收到无线信号，错误指示灯将作为无线通信指示灯，无线某个按下亮起，松开熄灭；
*/
uint8_t uc_rd_is_valid = 0;/*0:无线无效，1：无线有效*/

/*
通信指示灯：CAN正常收发，指示灯每250ms闪烁一次；
           CAN收发错误，指示灯每100ms闪烁一次，快闪；
*/
uint8_t uc_can0_tx_fault_sn     = 0;/*CAN0 发送错误标志*/
uint8_t uc_can0_rx_fault_sn     = 0;/*CAN0 接收错误标志*/
uint32_t ul_can0_no_data_rx_cnt = 0;/*CAN0 未接收数据计数*/

uint8_t gSpeedLEDFlickerTimeoutSn = 0;
uint32_t gSpeedLedTimeoutCnt = TIME_OUT_250MS;
/**
 * @brief LED 定时器函数
 */
void Main_LedTick(uint32_t tick)
{
  if (tick % TIME_OUT_100MS == 0)
	{
		if(ul_can0_total_rx_cnt != ul_can0_total_cnt_last)
		{
			ul_can0_total_cnt_last = ul_can0_total_rx_cnt;
			ul_can0_no_data_rx_cnt = 0;
		}
		else ul_can0_no_data_rx_cnt++;
  }
  if(tick%gSpeedLedTimeoutCnt == 0)
	{
		if(gSpeedLEDFlickerTimeoutSn == 1) gSpeedLEDFlickerTimeoutSn = 0;	
		else gSpeedLEDFlickerTimeoutSn = 1;
		
	}
}
void Main_LedCtrl(void)
{
	//CAN 接收错误判断,未收到报文
	if(ul_can0_no_data_rx_cnt > 10) uc_can0_rx_fault_sn = 1;
	else uc_can0_rx_fault_sn = 0;
	/*状态指示灯*/
	if(uc_enet_status_flag == 1) led_status(LED_ON);
	else led_status(LED_OFF);

	//CAN通信指示灯
	if(gSpeedLEDFlickerTimeoutSn == 1) led_can(LED_ON);
	else led_can(LED_OFF);
	
	if((uc_can0_rx_fault_sn == 1) || (uc_can0_tx_fault_sn == 1)) gSpeedLedTimeoutCnt = TIME_OUT_100MS;
	else gSpeedLedTimeoutCnt = TIME_OUT_250MS;

	//错误指示灯
  if(uc_rd_is_valid == 0)
  {
    if(uc_can0_rx_fault_sn == 1) led_error(LED_ON);
	  else led_error(LED_OFF);
  }
  else
  {
    if((uc_rd_key01 == 1) || (uc_rd_key02 == 1) || (uc_rd_key03 == 1) || (uc_rd_key04 == 1) || 
       (uc_rd_key05 == 1) || (uc_rd_key06 == 1) || (uc_rd_key07 == 1) || (uc_rd_key08 == 1) || 
       (uc_rd_key_emorgency_stop == 1))
    {
      led_error(LED_ON);
    }
    else led_error(LED_OFF);
  }
}
/**
 * @brief 软件初始化
 */
void Main_SwInit(void)
{
  task_config_init();
  parameter_config_init(); 
}
void Main_PF15_Config(void)
{
  rcu_periph_clock_enable(RCU_SYSCFG);

  gpio_mode_set(GPIOF,GPIO_MODE_INPUT,GPIO_PUPD_PULLDOWN,GPIO_PIN_15);
  nvic_irq_enable(EXTI10_15_IRQn,2,0);
  syscfg_exti_line_config(EXTI_SOURCE_GPIOF,EXTI_SOURCE_PIN15);
  exti_init(EXTI_15,EXTI_INTERRUPT,EXTI_TRIG_RISING);
  exti_interrupt_flag_clear(EXTI_15);
}
/**
 * @brief 硬件初始化
 * @note  1. 初始化硬件，包括时钟、GPIO、中断、串口、CAN、ADC、IIC、DMA、定时器等
 *        2. 初始化CAN、IIC、DMA、定时器等
 *        3. 初始化CAN、IIC、DMA、定时器等
 */
void Main_HwInit(void)
{
  SCB->VTOR = FLASH_BASE | 0x00008000;  
  board_init();
  app_input_init();
  Main_PF15_Config();
  app_output_init();
  app_can_init();
  drv_dac_init();
  I2C_Port_Init();
  Main_pca9555_init();

  timer4_init();
  g_inited = 1; //init success, task_500us can run

  SPI_Init();
  wireless_select_out(eNss,1);
  wireless_init();

  enet_rst(0);
	delay_10ms(100);
  enet_rst(1);
  enet_system_setup();

	Main_pca9555_out();
	MB_Master_T35ExpiredTimerInit(500); 
  di_data_redefine();
  user_app_rs485_initHandler();
	
	wdt_init(1500);
	systick_config();
}
volatile uint32_t ul_tick_500us = 0;
/**
 * @brief 500us定时器中断
 */
void task_500us(void) 
{
  ul_tick_500us++;
  g_out_timeout_cntr++;
  Main_LedTick(ul_tick_500us);
	Main_LedCtrl();
  lwip_tick();
  if (0 == g_inited)  return;
	if(ul_tick_500us%20 == 0) time_update();

  if(ul_tick_500us%200 == 0)//100ms
  {
    pi_disconnect_handle();
  }
	adc_multiplexing();
  
  if (ul_tick_500us%2 == 0) 
  {
    if(ut_controller_type.io == eEnable) app_can_recv();
    output_update();
  } 
  else 
  { 
    input_update();//
    if(ut_controller_type.io == eEnable) app_can_send();
    Can0_Tx_Fifo();
    Can1_Tx_Fifo();
  }
}
uint32_t ul_system_basic_tick = 0;/*时基，500us加1*/
/**
 * @brief 系统时钟中断处理函数,500us定时器中断
 */
void system_tick(void)
{
  ul_system_basic_tick++;

  task_500us();
  user_app_tick(ul_system_basic_tick);
  pt100_tick(ul_system_basic_tick);
}
/**
 * @brief FeeRTOS普通任务初始化
 */
void Main_Common_TaskInit(void)
{
  if(ut_os_task_config.task_1ms == eEnable)   Task_1ms_init();
  if(ut_os_task_config.task_5ms == eEnable)   Task_5ms_init();
  if(ut_os_task_config.task_10ms == eEnable)  Task_10ms_init();
  if(ut_os_task_config.task_20ms == eEnable)  Task_20ms_init();
  if(ut_os_task_config.task_50ms == eEnable)  Task_50ms_init();
  if(ut_os_task_config.task_100ms == eEnable) Task_100ms_init();
  if(ut_os_task_config.task_500ms == eEnable) Task_500ms_init();

  Task_mbTcp_slave_init();
  Task_mb485_master_init();//modbus rtu
}
/**
 * @brief 任务初始化，包括OS普通任务和LWIP堆栈初始化
 */
void Main_TaskInit(void)
{
  Main_Common_TaskInit();
  /* initilaize the LwIP stack */
  lwip_stack_init();
  /* Start the scheduler. */
  vTaskStartScheduler(); 
}
int32_t main(void) 
{
  Main_SwInit();
  in_select();
  Main_HwInit();

  Main_TaskInit();
  while (1) 
  {
  }
}




